﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Vibz.TeamAssignment.Common.Entity;
using Extensil.Common;

namespace Vibz.TeamAssignment
{
    internal partial class TaskGrid :UserControl
    {
        public const string AssignedToMe = "Assigned to me";
        public const string AssignedByMe = "Assigned by me";
        public const string ShowAll = "Show All";
        public delegate void TaskGridEventHandler(object sender, TaskGridEventArgs e);
        public delegate void TaskLoadEventHandler(object sender, TaskLoadEventArgs e);

        public event TaskGridEventHandler CellClick;
        public event TaskLoadEventHandler TaskLoadRequired;
        AssignmentClient Client
        {
            get;
            set;
        }
        internal Dictionary<TaskView, DeltaChange> DeltaChange
        {
            get;
            set;
        }
        internal List<TaskView> TaskList
        {
            get;
            set;
        }
        string CurrentSortColumn = String.Empty;
        ListSortDirection CurrentSortDirection;
        string Filters = String.Empty;
        int selectedTask = -1;
        public bool ShowNewTaskMenu
        {
            get;
            set;
        }

        public TaskGrid()
        {
            InitializeComponent();
        }
        protected override void OnLoad(EventArgs e)
        {
            if(!ShowNewTaskMenu)
                btnAddTask.Visible = false;
        }
        public void Load(List<TaskView> taskList, AssignmentClient aClient)
        {
            Load(taskList, null, aClient);
        }
        public void Load(List<TaskView> taskList, Dictionary<TaskView, DeltaChange> delta, AssignmentClient aClient)
        {
            Client = aClient;
            TaskList = taskList;
            DeltaChange = delta;
            selectedTask = -1;
            if(dgvTaskList.SelectedRows.Count > 0)
                selectedTask = TaskView.DeSerialize((DataRowView)dgvTaskList.SelectedRows[0].DataBoundItem).Task.TaskID;
            dgvTaskList.DataSource = TaskView.Serialize(taskList);
        }

        public void Clear()
        {
            TaskList = null;
            CurrentSortColumn = String.Empty;
            CurrentSortDirection = ListSortDirection.Ascending;
            Filters = String.Empty;
            dgvTaskList.DataSource = null;
            lblFilter.Text = "Showing all tasks.";
            showAllToolStripMenuItem.Checked = true;
            requestTypeToolStripMenuItem.Checked = false;
            assignedDateToolStripMenuItem.Checked = false;
            dueDateToolStripMenuItem.Checked = false;
            taskGroupToolStripMenuItem1.Checked = false;
        }
        void dgvTaskList_DataSourceChanged(object sender, EventArgs e)
        {
            foreach(DataGridViewColumn dc in dgvTaskList.Columns)
                dc.Visible = false;

            string colSeq = System.Configuration.ConfigurationManager.AppSettings["TaskViewColumnSequence"];
            string[] colNames = Client.GetViewColumnSequence();

            lblCount.Text = "Count: " + dgvTaskList.Rows.Count.ToString();

            int i = 0;
            foreach(string column in colNames)
            {
                if(dgvTaskList.Columns.Contains(column.Trim()))
                {
                    dgvTaskList.Columns[column.Trim()].Visible = true;
                    dgvTaskList.Columns[column.Trim()].DisplayIndex = i++;
                }
            }
            if(dgvTaskList.Rows.Count > 0)
            {
                dgvTaskList.SelectionChanged -= new System.EventHandler(dgvTaskList_SelectionChanged);

                dgvTaskList.Visible = true;

                if(showAllToolStripMenuItem.Checked)
                    LoadFilters();
                else
                    ApplyFilter();

                ResetFilter(showAllToolStripMenuItem.Checked);

                SortList(CurrentSortColumn, CurrentSortDirection);

                HighLightTask();

                dgvTaskList.SelectionChanged += new System.EventHandler(dgvTaskList_SelectionChanged);

                SelectPrevious();
            }
            else
                dgvTaskList.Visible = false;
        }
        void SelectPrevious()
        {
            if(dgvTaskList.Rows.Count > 0)
                dgvTaskList.Rows[0].Selected = false;
            if(selectedTask != -1)
            {
                foreach(DataGridViewRow dr in dgvTaskList.Rows)
                {
                    Task task = TaskView.DeSerialize((DataRowView)dr.DataBoundItem).Task;
                    if(selectedTask == task.TaskID)
                    {
                        dr.Selected = true;
                        break;
                    }
                }
            }
        }
        void LoadFilters()
        {
            // Set TaskGroup Filter
            taskGroupToolStripMenuItem1.DropDown.Items.Clear();
            taskGroupToolStripMenuItem1.DropDown.Items.Add(ClearFilterMenuItem);
            List<TaskGroup> grps = Client.GetDistinctTaskGroup(TaskList);
            foreach(TaskGroup tg in grps)
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(tg.Title,
                    null, filterToolStripMenuItem_Click);
                item.Name = tg.Title;
                item.Tag = tg;
                item.CheckOnClick = true;
                taskGroupToolStripMenuItem1.DropDown.Items.Add(item);
            }

            // Set RequestType Filter
            requestTypeToolStripMenuItem.DropDown.Items.Clear();
            requestTypeToolStripMenuItem.DropDown.Items.Add(ClearFilterMenuItem);
            string[] reqTypes = new string[] { "Requested", "Assigned" };
            foreach(string text in reqTypes)
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(text,
                    null, filterToolStripMenuItem_Click);
                item.Name = text;
                item.Tag = text == "Requested" ? true : false;
                item.CheckOnClick = true;
                requestTypeToolStripMenuItem.DropDown.Items.Add(item);
            }

            // Set AssignDate Filter
            assignedDateToolStripMenuItem.DropDown.Items.Clear();
            assignedDateToolStripMenuItem.DropDown.Items.Add(ClearFilterMenuItem);
            Dictionary<int, string> dates =
                Client.GetDistinctAssignedDateTimeSpan(TaskList);
            foreach(int date in dates.Keys)
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(dates[date],
                    null, filterToolStripMenuItem_Click);
                item.Name = date.ToString();
                item.Tag = date;
                item.CheckOnClick = true;
                assignedDateToolStripMenuItem.DropDown.Items.Add(item);
            }

            // Set DueDate Filter
            dueDateToolStripMenuItem.DropDown.Items.Clear();
            dueDateToolStripMenuItem.DropDown.Items.Add(ClearFilterMenuItem);
            dates = Client.GetDistinctDueDateTimeSpan(TaskList);
            foreach(int date in dates.Keys)
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(dates[date],
                    null, filterToolStripMenuItem_Click);
                item.Name = date.ToString();
                item.Tag = date;
                item.CheckOnClick = true;
                dueDateToolStripMenuItem.DropDown.Items.Add(item);
            }

            // Set Assignment
            assignmentToolStripMenuItem.DropDown.Items.Clear();
            assignmentToolStripMenuItem.DropDown.Items.Add(ClearFilterMenuItem);
            string[] assTypes = new string[] { AssignedToMe, AssignedByMe };
            foreach(string assType in assTypes)
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(assType,
                    null, filterToolStripMenuItem_Click);
                item.Name = assType;
                item.Tag = assType;
                item.CheckOnClick = true;
                assignmentToolStripMenuItem.DropDown.Items.Add(item);
            }
        }
        void HighLightTask()
        {
            // Highlight new tasks
            if(DeltaChange != null)
            {
                foreach(TaskView tv in DeltaChange.Keys)
                {
                    foreach(DataGridViewRow dr in dgvTaskList.Rows)
                    {
                        Task task = TaskView.DeSerialize((DataRowView)dr.DataBoundItem).Task;
                        if(tv.Task.TaskID == task.TaskID)
                        {
                            dr.DefaultCellStyle.BackColor = Color.LightYellow;
                            break;
                        }
                    }
                }
            }

            // Highlight task status - breached, risk, assigned
            foreach(DataGridViewRow dr in dgvTaskList.Rows)
            {
                TaskView tView = TaskView.DeSerialize((DataRowView)dr.DataBoundItem);
                if(DateTime.Now.CompareTo(tView.Task.DueDate) > 0)
                {
                    dr.DefaultCellStyle.ForeColor = Color.Red;
                }
                else if(DateTime.Now.AddDays(2).CompareTo(tView.Task.DueDate) >= 0)
                {
                    dr.DefaultCellStyle.ForeColor = Color.DarkOrange;
                }
            }
        }
        ToolStripMenuItemGrouped ClearFilterMenuItem
        {
            get
            {
                ToolStripMenuItemGrouped item = new ToolStripMenuItemGrouped(ShowAll,
                                        null, filterToolStripMenuItem_Click);
                item.Tag = null;
                item.Checked = true;
                item.CheckOnClick = true;
                return item;
            }
        }

        private void dgvTaskList_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            Console.WriteLine(DateTime.Now.ToLongTimeString() + "\tdgvTaskList_CellClick");
            if(this.CellClick != null && e.RowIndex >= 0)
            {
                TaskGridEventArgs args = new TaskGridEventArgs();
                args.Task = TaskView.DeSerialize((DataRowView)dgvTaskList.Rows[e.RowIndex].DataBoundItem).Task;
                this.CellClick(this, args);
            }
        }
        public void SelectRow(int taskId)
        {
            if(taskId != -1)
            {
                foreach(DataGridViewRow dr in dgvTaskList.Rows)
                {
                    Task task = TaskView.DeSerialize((DataRowView)dr.DataBoundItem).Task;
                    dr.Selected = (taskId == task.TaskID);
                }
            }

        }
        private void btnAddTask_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
            {
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.AddNew, -1));
                foreach(DataGridViewRow dr in dgvTaskList.SelectedRows)
                    dr.Selected = false;
            }
        }

        private void dgvTaskList_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            DataGridViewColumn sortColumn = dgvTaskList.Columns[e.ColumnIndex];
            SortList(sortColumn);
        }
        void SortList(DataGridViewColumn sortColumn)
        {
            ListSortDirection direction;
            if(!String.IsNullOrEmpty(CurrentSortColumn))
            {
                if(CurrentSortColumn == sortColumn.Name &&
                    dgvTaskList.SortOrder == SortOrder.Descending)
                {
                    direction = ListSortDirection.Descending;
                }
                else
                {
                    direction = ListSortDirection.Ascending;
                    dgvTaskList.Columns[CurrentSortColumn].HeaderCell.SortGlyphDirection = SortOrder.None;
                }
            }
            else
            {
                direction = ListSortDirection.Ascending;
            }

            SortList(sortColumn.Name, direction);
        }
        void SortList(string column, ListSortDirection direction)
        {
            if(String.IsNullOrEmpty(column))
                return;

            DataGridViewColumn sortColumn = dgvTaskList.Columns[column];

            dgvTaskList.Sort(sortColumn, direction);

            sortColumn.HeaderCell.SortGlyphDirection =
                direction == ListSortDirection.Ascending
                    ? SortOrder.Ascending
                    : SortOrder.Descending;

            CurrentSortColumn = sortColumn.Name;
            CurrentSortDirection = direction;

            HighLightTask();
        }

        private void filterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            bool clearFilters = false;

            ToolStripItem tsi = (ToolStripMenuItem)sender;
            if(tsi.Tag != null && tsi.Tag.ToString() == "-1")
                clearFilters = true;

            ResetFilter(clearFilters);
        }

        void ResetFilter(bool clearFilters)
        {
            Filters = String.Empty;

            // Request Type
            string filter = ParseFilter(requestTypeToolStripMenuItem,
                    delegate(object obj)
                    {
                        return string.Format(
                            ViewColumns.IsRequest.ToString() + " = '{0}'", ((bool)obj).ToString());
                    },
                    clearFilters);
            if(!String.IsNullOrEmpty(filter))
                Filters += ((!String.IsNullOrEmpty(Filters)) ? " and " : "") + filter;

            // Task Group
            filter = ParseFilter(taskGroupToolStripMenuItem1,
                    delegate(object obj)
                    {
                        return string.Format(
                            ViewColumns.TaskGroupID.ToString() + " = '{0}'", ((TaskGroup)obj).ID.ToString());
                    },
                    clearFilters);
            if(!String.IsNullOrEmpty(filter))
                Filters += ((!String.IsNullOrEmpty(Filters)) ? " and " : "") + filter;

            // Assign Date
            filter = ParseFilter(assignedDateToolStripMenuItem,
                    delegate(object obj)
                    {
                        return string.Format(
                            ViewColumns.AssignDate.ToString() + " > '#{0}#'",
                            DateTime.Today.AddDays(-1 * int.Parse(obj.ToString())).ToString("MM/dd/yyyy"));
                    },
                    clearFilters);
            if(!String.IsNullOrEmpty(filter))
                Filters += ((!String.IsNullOrEmpty(Filters)) ? " and " : "") + filter;

            // Due Date
            filter = ParseFilter(dueDateToolStripMenuItem,
                    delegate(object obj)
                    {
                        return string.Format(
                            ViewColumns.DueDate.ToString() + " < '#{0}#'",
                            DateTime.Today.AddDays(int.Parse(obj.ToString())).ToString("MM/dd/yyyy"));
                    },
                    clearFilters);
            if(!String.IsNullOrEmpty(filter))
                Filters += ((!String.IsNullOrEmpty(Filters)) ? " and " : "") + filter;

            // Assignment
            filter = ParseFilter(assignmentToolStripMenuItem,
                    delegate(object obj)
                    {
                        string assFilter = String.Empty;
                        if((assignmentToolStripMenuItem.DropDown.Items[AssignedByMe] != null
                            && ((ToolStripMenuItem)assignmentToolStripMenuItem.DropDown.Items[AssignedByMe]).Checked)
                            || (assignmentToolStripMenuItem.DropDown.Items[ShowAll] != null
                            && ((ToolStripMenuItem)assignmentToolStripMenuItem.DropDown.Items[ShowAll]).Checked))
                            assFilter += ((!String.IsNullOrEmpty(assFilter)) ? " or " : "") + string.Format(
                                ViewColumns.AssignBy.ToString() + " = '{0}'", AssignmentClient.CurrentUser);

                        if((assignmentToolStripMenuItem.DropDown.Items[AssignedToMe] != null
                            && ((ToolStripMenuItem)assignmentToolStripMenuItem.DropDown.Items[AssignedToMe]).Checked)
                            || (assignmentToolStripMenuItem.DropDown.Items[ShowAll] != null
                            && ((ToolStripMenuItem)assignmentToolStripMenuItem.DropDown.Items[ShowAll]).Checked))
                            assFilter += ((!String.IsNullOrEmpty(assFilter)) ? " or " : "") + string.Format(
                                ViewColumns.AssignTo.ToString() + " = '{0}'", AssignmentClient.CurrentUser);

                        return assFilter;
                    },
                    clearFilters);
            if(!String.IsNullOrEmpty(filter))
                Filters += ((!String.IsNullOrEmpty(Filters)) ? " and " : "") + "(" + filter + ")";

            ApplyFilter();
        }
        void ApplyFilter()
        {
            if(String.IsNullOrEmpty(Filters))
                showAllToolStripMenuItem.Checked = true;
            (dgvTaskList.DataSource as DataTable).DefaultView.RowFilter
                = Filters;

            lblCount.Text = "Count: " + (dgvTaskList.DataSource as DataTable).DefaultView.Count.ToString();

            filterMenu.ToolTipText = Filters.Replace(" and ", "\r\nand ");

            lblFilter.Text = (String.IsNullOrEmpty(Filters.Trim()))
                ? "Showing all tasks."
                : "Filter: " + (Filters.Length < 70 ? Filters : Filters.Substring(0, 70) + "...");
            lblFilter.ToolTipText = (String.IsNullOrEmpty(Filters.Trim()))
                ? ""
                : filterMenu.ToolTipText;
            lblFilter.DoubleClick += new EventHandler(lblFilter_DoubleClick);

            HighLightTask();
        }

        void lblFilter_DoubleClick(object sender, EventArgs e)
        {
            if(!String.IsNullOrEmpty(((ToolStripLabel)sender).ToolTipText))
                AlertBox.ShowDialog(((ToolStripLabel)sender).ToolTipText);
        }

        delegate string filterParseDelegate(object tag);

        string ParseFilter(ToolStripMenuItem mItem, filterParseDelegate parseDelegate, bool clearFilters)
        {
            string filter = String.Empty;
            foreach(ToolStripItem item in mItem.DropDown.Items)
            {
                ToolStripMenuItemGrouped mi = (ToolStripMenuItemGrouped)item;
                if(clearFilters && mi.Tag == null)
                {
                    mi.Checked = true;
                    ((ToolStripMenuItem)mi.OwnerItem).Checked = false;
                    break;
                }
                if(mi.Checked)
                {
                    if(mi.Tag == null)
                    {
                        ((ToolStripMenuItem)mi.OwnerItem).Checked = false;
                        break;
                    }

                    filter = parseDelegate(mi.Tag);

                    ((ToolStripMenuItem)mi.OwnerItem).Checked = true;
                    showAllToolStripMenuItem.Checked = false;
                    break;
                }
            }
            return filter;
        }

        private void dgvTaskList_RowContextMenuStripNeeded(object sender,
            DataGridViewRowContextMenuStripNeededEventArgs e)
        {
            Task task = TaskView.DeSerialize((DataRowView)dgvTaskList.Rows[e.RowIndex].DataBoundItem).Task;
            GridViewContextMenu.Tag = task;
            newSiblingTaskToolStripMenuItem.Visible = (task.ParentID != -1);
            viewParentTaskToolStripMenuItem1.Visible = (task.ParentID != -1);

            e.ContextMenuStrip = GridViewContextMenu;

            dgvTaskList.SelectionChanged -= new System.EventHandler(dgvTaskList_SelectionChanged);

            if(dgvTaskList.SelectedRows.Count > 0)
                dgvTaskList.SelectedRows[0].Selected = false;
            dgvTaskList.Rows[e.RowIndex].Selected = true;

            dgvTaskList.SelectionChanged += new System.EventHandler(dgvTaskList_SelectionChanged);

        }

        private void editToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.Edit,
                    ((Task)GridViewContextMenu.Tag).TaskID));
        }

        private void newSubTaskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.AddChild,
                    ((Task)GridViewContextMenu.Tag).TaskID));
        }

        private void newSiblingTaskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.AddSibling, 
                    ((Task)GridViewContextMenu.Tag).ParentID));
        }

        private void viewParentTaskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.Edit, 
                    ((Task)GridViewContextMenu.Tag).ParentID));
        }

        private void dgvTaskList_SelectionChanged(object sender, EventArgs e)
        {
            if(this.CellClick != null && dgvTaskList.SelectedRows.Count > 0)
            {
                TaskGridEventArgs args = new TaskGridEventArgs();
                args.Task = TaskView.DeSerialize((DataRowView)dgvTaskList.SelectedRows[0].DataBoundItem).Task;
                // this.CellClick(this, args);
            }
        }

        private void openInNewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(this.TaskLoadRequired != null)
                this.TaskLoadRequired(this, new TaskLoadEventArgs(TaskOperation.EditInNew,
                    ((Task)GridViewContextMenu.Tag).TaskID));
        }

        private void viewAssignmentHistoryToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            AssignmentHistory aHistort = new AssignmentHistory(Client, ((Task)GridViewContextMenu.Tag).TaskID);
            aHistort.Show();
        }

        private void viewTaskFlowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TaskFlow tFlow = new TaskFlow(Client, (Task)GridViewContextMenu.Tag);
            tFlow.Show();
        }

        private void statusRequestToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client.RequestTaskStatus((Task)GridViewContextMenu.Tag);
        }

        private void instantMessageToAllStakeholdersToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client.SendInstantMessageToAllStakeholders((Task)GridViewContextMenu.Tag);
        }

        private void instantMessageToCurrentAssignedUserToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Client.SendInstantMessageToCurrentAssignedUser((Task)GridViewContextMenu.Tag);
        }
    }
}
